Core Animation 使用 action 对象实现图层的隐式动画行为。action 对象遵守 CAAction
协议,并定义一些在图层上执行的相关行为。所有的 CAAnimation 对象实现了该协议,并且这些对象通常被分配在图层属性改变时执行。
动画属性是 action 的一种类型,你也可以定义任何包含你想要的行为的 action 。但为了实现该目的,你必须定义自己的 action 对象,并将它们与你 app 的图层对象关联。
自定义的 Action 对象遵守 CAAction 协议
去创建你自己的 action 对象,使你的类遵守 CAAction 协议,并实现 runActionForKey:object:arguments:
方法。在该方法中,使用可用的信息去执行你想在图层上应用的 actions 。你可能使用该方法给图层添加一个动画对象,或执行其他的任务。
当你定义 action 对象时,你必须决定 action 怎样被触发。触发器为 action 定义键,后面你使用该键注册 action。Action 对象在下面的情况下会被触发:
- 图层的属性值改变时,可以是图层的任意属性,不仅是可以动画的属性。(你也可以将你给图层添加的自定义属性与 action 关联。)识别 action 的键就是属性的名字。
- 图层变为可见的或被添加到图层层级结构中。识别 action 的键是
kCAOnOrderIn
。 - 图层从图层层级结构中被移除。识别 action 的键是
kCAOnOrderOut
。 - 图层即将参与过渡动画。识别 action 的键是
kCATransition
。
Action 对象必须安装在图层上才能生效
在 action 可被执行之前,图层对象需要寻找响应的 action 对象去执行。图层相关的 actions 的键是被修改属性的名字,或可识别 action 的一个特别的字符串。当图层上发生合适的事件时,图层会调用 actionForKey:
方法去用于 action 对象关联的键去搜索 action 对象。在搜索过程中,你的 app 可以在几个点插入自己,并为该键提供相关的 action 对象。
Core Animation 通过下面的顺序查找 action 对象:
如果图层有 delegate,并且 delegate 实现了
actionForLayer:forKey:
方法,图层调用该方法。delegate 必须做下面的其中一个:- 通过给的键返回 action 对象。
- 如果它没有处理 action,返回 nil。该情况下搜索继续。
- 返回 NSNull 对象,该情况下搜索立即结束。
图层在图层 actions 字典中查询给定的键。
- 图层在
style
字典中查询包含键的 actions 字典。(换言之,style
字典包含actions
键,其值也是字典 。图层在第二个字典中,用给定的键去查询。) - 图层调用
defaultActionForKey:
类方法。 - 图层执行由 Core Animation 定义的隐式 action (如果有的话)。
如果你在任意合适的搜索点提供了一个 action 对象,图层会停止搜索,并执行返回的 action 对象。它发现一个 action 对象时,图层调用对象的 runActionForKey:object:arguments:
方法去执行该 action。如果你对于给定的键定义的 action 已经是 CAAnimation
的实例,你可以使用默认的实现去执行动画。如果你定义你自己的自定义对象遵守了 CAAction
协议,你必须使用该方法的对象实现来采取任何适当的操作。
你在哪安装 action 对象取决于你想如何修改图层。
- 对于只想应用某些具体情况的 action,或已经使用 delegate 对象的图层,提供 delegate 并实现它的
actionForLayer:forKey:
方法。 - 对于通常不使用委托的图层对象,请将 action 添加到图层的
actions
字典中。 - 对于与在图层对象上定义的自定义属性相关的 action ,请将该 action 包含在图层的
style
字典中。 - 对于对图层行为至关重要的 action,对图层进行子类化,并重写
defaultActionForKey:
方法。
例 6-1 展示了使用提供的 action 对象的 delegate 方法的实现。在这种情况下,delegate 查找图层 contents
属性的改变,并且使用过渡动画将新内容交换到相应位置。
例 6-1 使用图层委托对象提供
使用 CATransaction 类将 Actions 暂时禁用
你可以使用 CATransaction 类暂时禁用图层的 actions 。你改变图层属性时, Core Animation 通常创建一个隐式事务对象去动画改变。如果你不想动画改变,你可以通过创建一个显式事务,并且将 kCATransactionDisableActions
属性设置为 true 来禁用隐式动画。例 6-2 展示了从图层树移除指定图层时,如果用代码禁用动画。
例 6-2 暂时禁用图层的 actions
关于使用事务对象管理动画行为的更多信息,请参见显示事务允许你改变动画参数。